import dayjs from 'dayjs'
import browser from "webextension-polyfill"
import Utf8 from 'crypto-js/enc-utf8'
import AES from 'crypto-js/aes'
import ECB from 'crypto-js/mode-ecb'
import Pkcs7 from 'crypto-js/pad-pkcs7'

export const sdTime96:string[] = ['00:15', '00:30', '00:45', '01:00', '01:15', '01:30', '01:45', '02:00', '02:15', '02:30', '02:45', '03:00', '03:15', '03:30', '03:45', '04:00', '04:15', '04:30', '04:45', '05:00', '05:15', '05:30', '05:45', '06:00', '06:15', '06:30', '06:45', '07:00', '07:15', '07:30', '07:45', '08:00', '08:15', '08:30', '08:45', '09:00', '09:15', '09:30', '09:45', '10:00', '10:15', '10:30', '10:45', '11:00', '11:15', '11:30', '11:45', '12:00', '12:15', '12:30', '12:45', '13:00', '13:15', '13:30', '13:45', '14:00', '14:15', '14:30', '14:45', '15:00', '15:15', '15:30', '15:45', '16:00', '16:15', '16:30', '16:45', '17:00', '17:15', '17:30', '17:45', '18:00', '18:15', '18:30', '18:45', '19:00', '19:15', '19:30', '19:45', '20:00', '20:15', '20:30', '20:45', '21:00', '21:15', '21:30', '21:45', '22:00', '22:15', '22:30', '22:45', '23:00', '23:15', '23:30', '23:45', '24:00']

export const promisetTimeOut = (timeOut = 500) => {
  return new Promise((resolve) => {
    setTimeout(resolve, timeOut)
  })
}

export const runTest = (type = '') => {
  setInterval(() => {
    console.log(`${type}_Date.now()`, dayjs().format('HH:mm:ss'))
  }, 1000)
}

export const cookieListToStr = (data:browser.Cookies.Cookie[]) => {
  let str = ''
  data.forEach(({name, value}) => {
    str += `${name}=${value};`
  })
  return str
}

/**
 * 判断是否有 值
 * @param val any
 * @returns boolean
 */
export const hasValue = (val:any) => {
  if (String(val) === '0') return true
  return Boolean(val)
}

/*
* 对账号密码加密 AES中的ECB模式
 */
export function encrypt (word: object | string, keyStr?: string) {
  const jsonString = typeof word === 'object' ? JSON.stringify(word) : word
  const keys = keyStr || 'ahdcloud20210425'
  const key = Utf8.parse(keys)
  const srcs = Utf8.parse(jsonString)
  const encrypted = AES.encrypt(srcs, key, {
    mode: ECB,
    padding: Pkcs7
  })
  return encrypted.toString()
}


// 将数据存储到本地存储中
export const saveDataToLocalStorage = (data:any,key:string)=> {
  if(chrome?.storage?.local){
    chrome.storage.local.set({ [key]: data }, function() {
      if (chrome.runtime.lastError) {
        console.error('存储数据时出错: ' + chrome.runtime.lastError.message);
      }
    });
  } else {
    window.localStorage.setItem(key,data)
  }
}


// 同步获取本地存储的数据
export function getDataFromLocalStorageSync(key:string) {
  return new Promise((resolve, reject) => {
    if(chrome?.storage?.local) {
      chrome.storage.local.get(key, function(result) {
        if (chrome.runtime.lastError) {
          reject(chrome.runtime.lastError);
        } else {
          resolve(result[key]);
        }
      });
    } else {
      const value = window.localStorage.getItem(key)
      value && resolve(value)
      !value && reject(new Error(`window.localStorage.getItem ${key}, 获取失败`))
    }
  });
}

// 获取本地存储
export const getDataFromLocalStorage =  async (key:string)=> { 
  try {
    const data = await getDataFromLocalStorageSync(key);
    return data
  } catch (error:any) {
    console.error('获取数据时出错:', error.message);
  }
}

/**
 * 判断是否JSON字符
 * @param str 字符串
 * @returns boolean 是否JSON字符
 */
export const validateJSON = (str:any) => {
  if (typeof str !== 'string') {
    console.error('It is not a string!')
    return false
  }
  try {
    const obj = JSON.parse(str)
    if (obj && typeof obj === 'object') {
      return true
    } else {
      return false
    }
  } catch (e) {
    console.error('error：' + str + '!!!' + e)
    return false
  }
}


/**
 * 判断是否JSON字符
 * @param str 字符串
 * @returns {result:false, jsonData:null} 是否JSON字符、解析后的JSON对象
 */
export const validateAndParseJSON = (str:any) => {
  if (typeof str !== 'string') {
    console.error('It is not a string!')
    return {result:false, jsonData:null}
  }
  try {
    const jsonData = JSON.parse(str)
    return {result:true, jsonData}
  } catch (e) {
    console.error('error：' + str + '!!!' + e)
    return {result:false, jsonData:null}
  }
}

/** 导出json数据 */
export const exportJson = (fileName:string, jsonStr:any) => {
  // 创建a标签
  let link: HTMLAnchorElement | null = document.createElement('a')
  link.download = fileName + '.json'
  // 创建blob
  const blob = new Blob([jsonStr])
  // 创建临时url
  const href = URL.createObjectURL(blob)
  link.href = href
  // 调用click
  link.click()
  link = null
  // 销毁
  URL.revokeObjectURL(href)
}

export const objToFormdata = (data:Record<string, any>, fileName = ''):FormData => {
  const formData = new FormData()
  for(const key in data) {
    if(data[key] instanceof Blob && fileName) {
      formData.append(key, data[key], fileName)
      continue
    }
    formData.append(key, data[key])
  }
  return formData
}

export const getCookieValByKey = (cookie:string, key:string) => {
  const reg1 = new RegExp(`^${key}`)
  const reg2 = new RegExp(`${key}`)
  return cookie?.split(';')?.map(val => val.trim())?.find(val => reg1.test(val))?.replace(reg2,'') || ''
}

/** 获取需要设置的系统日期 */
export const getDdifferenceDate = (day:number, type: 'date' | 'month' = 'date') => {
  let pdate = dayjs().format('YYYY-MM-DD')

  if(day < 0) (pdate = dayjs(pdate).subtract(Math.abs(day), 'day').format('YYYY-MM-DD'))
  if(day > 0) (pdate = dayjs(pdate).add(Math.abs(day), 'day').format('YYYY-MM-DD'))

  if(type === 'month') {
    pdate = pdate.slice(0, 7)
  }

  return pdate
}

/** 24点的数据转为96点 */
export const dataPrice24To96 = (list?:Array<any>):Array<any> => {
  if(list?.length === 96) return list

  const dealList:Array<any> = []
  if(!list?.length) return dealList
  
  if(list.length === 24) {
    list.forEach(val => {
      dealList.push(val,val,val,val)
    })
  }

  if(dealList.length !== 96) return Array.from({length:96}).fill(null)
  return dealList
}

export const dataQuan24To96 = (list?:Array<any>):Array<any> => {
  if(list?.length === 96) return list

  const dealList:Array<any> = []
  if(!list?.length) return dealList
  
  if(list.length === 24) {
    list.forEach(val => {
      let value = /^([\d|\-|])?[\d|\.]+$/.test(val) ? Number(val)/4 : ''
      dealList.push(value,value,value,value)
    })
  }

  if(dealList.length !== 96) return Array.from({length:96}).fill(null)
  return dealList
}

/**
 * 获取一天 时刻的集合
 * @param type { 24 | 25 | 96 | 97|'all' | 1441} all表示时分（00:00-23:59），1441表示到00:00-24:00
 * @returns Array
 */
type PointsType = 24 | 25 | 96 | '96_2' | 97 | 'all' | 1441
export const getTimePoints = (type: PointsType = 24, startIndex = 0):string[] => {
  const points:string[] = []
  switch (type) {
    case 24:
    case 25: {
      let i = startIndex !== 0 ? startIndex : 0
      for (; i < type; i++) {
        points.push(`${String(i).padStart(2, '0')}:00`)
      }
      return points
    }
    case 97:
    case '96_2':
    case 96: {
      const quarters = ['00', '15', '30', '45']
      for (let i = 0; i < 25; i++) {
        const pointHour = `${String(i).padStart(2, '0')}`
        quarters.forEach(quarter => points.push(`${pointHour}:${quarter}`))
      }
      if (type === '96_2') return points.slice(0, -4)
      if (type === 97) return points.slice(0, -3)
      return points.slice(1, -3)
    }
    case 1441:
    case 'all': {
      const hour = 24
      const minute = 60
      for (let h = 0; h < hour; h++) {
        const list = Array.from({ length: minute }, (v, m) => {
          return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`
        })
        points.push(...list)
      }
      if (type === 1441) points.push('24:00')
      return points
    }
    default:
      return points
  }
}


const timePoints96_2 = getTimePoints('96_2')
export const getTimeRangePoints = (rangeList:Array<[string,string]>):string[] => {
  const resultList:string[] = []
  rangeList.forEach(([start, end]) => {
    let [startIndex, endIndex] = [
      timePoints96_2.findIndex(time => time === start),
      timePoints96_2.findIndex(time => time === end)
    ]
    if(startIndex === -1 || endIndex === -1) {
      console.error('getTimeRangePoints 入参有误', rangeList)
      return
    }
    if(startIndex > endIndex) [startIndex, endIndex] = [endIndex, startIndex]
    
    resultList.push(...timePoints96_2.slice(startIndex, endIndex + 1))
  })

  return resultList
}


/** 提取两种字符串之前的字符串 */
export const extractBetweenStrings = (text:string, start:string, end:string) => {
  // 构造正则表达式，使用非贪婪模式 ?，以匹配第一个 end 出现的地方
  const regex = new RegExp(`${start}(.*?)${end}`);
  const match = text.match(regex);
  
  // 如果匹配到了，返回匹配的中间部分，否则返回空字符串
  return match ? match[1] : null;
}

/**
 * 将 Base64 数据转换为 Blob 对象
 * @param base64 - Base64 编码的字符串
 * @param mimeType - 数据的 MIME 类型（可选）
 * @returns Blob 对象
 */
export const base64ToBlob = (base64: string, mimeType: string = ''): Blob =>{
  // 解码 Base64 为二进制字符串
  const binaryString = atob(base64);

  // 转换为字节数组
  const byteArray = new Uint8Array(binaryString.length);
  for (let i = 0; i < binaryString.length; i++) {
    byteArray[i] = binaryString.charCodeAt(i);
  }

  // 创建 Blob
  return new Blob([byteArray], { type: mimeType });
}

/** 在for循环中也不会重复的时间戳 */
export const generateUniqueTimestamp = (() => {
  let counter = 0; // 内部计数器，仅在闭包内维护
  return () => {
      const baseTime = Date.now(); // 当前时间戳（毫秒）
      return `${baseTime}_${counter++}`; // 组合时间戳和计数器，生成唯一值
  };
})();


/** 获取数据类型 */
type GetDataTypeReturnValue = 'undefined' | 'null' | 'boolean' | 'number' | 'bigint' | 'string' | 'symbol' | 'object' | 'array' | 'function' | 'date' | 'regexp' | 'error' | 'promise' | 'map' | 'weakmap' | 'set' | 'weakset' | 'arraybuffer' | 'sharedarraybuffer' | 'dataview' | 'int8array' | 'uint8array' | 'uint8clampedarray' | 'int16array' | 'uint16array' | 'int32array' | 'uint32array' | 'float32array' | 'float64array' | 'bigint64array' | 'biguint64array' | 'arguments' | 'math' | 'json' | 'generatorfunction' | 'asyncfunction' | 'module';
export const getDataType = (data:any):GetDataTypeReturnValue => Object.prototype.toString.call(data).slice(8, -1).toLowerCase() as GetDataTypeReturnValue
